import { createRouter, createWebHashHistory } from 'vue-router'
import type {
  Router,
  RouteLocationNormalized,
  RouteRecordNormalized,
  RouteRecordRaw
} from 'vue-router'
import { isUrl } from '@/utils/is'
import { omit, cloneDeep } from 'lodash-es'

const modules = import.meta.glob('@/views/**/*.vue')
/* Layout */
export const Layout = () => import('@/layout/Layout.vue')

export const getParentLayout = () => {
  return () =>
    new Promise((resolve) => {
      resolve({
        name: 'ParentLayout'
      })
    })
}

export const getRawRoute = (route: RouteLocationNormalized): RouteLocationNormalized => {
  if (!route) return route
  const { matched, ...opt } = route
  return {
    ...opt,
    matched: (matched
      ? matched.map((item) => ({
          meta: item.meta,
          name: item.name,
          path: item.path
        }))
      : undefined) as RouteRecordNormalized[]
  }
}
// 前端控制路由生成
// export const generateRoutesByFrontEnd = (
//   routes: AppRouteRecordRaw[],
//   keys: string[],
//   basePath = '/'
// ): AppRouteRecordRaw[] => {
//   const res: AppRouteRecordRaw[] = []
//   for (const route of routes) {
//     const meta = route.meta ?? {}
//     // skip some route
//     if (meta.hidden && !meta.canTo) {
//       continue
//     }

//     let data: Nullable<AppRouteRecordRaw> = null

//     let onlyOneChild: Nullable<string> = null
//     if (route.children && route.children.length === 1 && !meta.alwaysShow) {
//       onlyOneChild = (
//         isUrl(route.children[0].path)
//           ? route.children[0].path
//           : pathResolve(pathResolve(basePath, route.path), route.children[0].path)
//       ) as string
//     }

//     // 开发者可以根据实际情况进行扩展
//     for (const item of keys) {
//       // 通过路径去匹配
//       if (isUrl(item) && (onlyOneChild === item || route.path === item)) {
//         data = Object.assign({}, route)
//       } else {
//         const routePath = (onlyOneChild ?? pathResolve(basePath, route.path)).trim()
//         if (routePath === item || meta.followRoute === item) {
//           data = Object.assign({}, route)
//         }
//       }
//     }

//     // recursive child routes
//     if (route.children && data) {
//       data.children = generateRoutesByFrontEnd(
//         route.children,
//         keys,
//         pathResolve(basePath, data.path)
//       )
//     }
//     if (data) {
//       res.push(data as AppRouteRecordRaw)
//     }
//   }
//   return res
// }

export const generateRoutesByFrontEnd = (
  route: AppRouteRecordRaw[],
  asyncRouterMap: string[],
  p_path
): AppRouteRecordRaw[] => {
  const arr1: AppRouteRecordRaw[] = []
  for (const asyncRouterElement of asyncRouterMap) {
    const routeElement = route.find(
      (routeItem) => routeItem['path'].replace(/\//g, '') === asyncRouterElement.path
    )
    // 如果后端路由表中没有该菜单或 status 为 2(隐藏) 直接跳过
    if (!routeElement) continue
    // eslint-disable-next-line no-unused-vars
    const { children, ...res } = asyncRouterElement
    p_path ? (res.p_path = p_path) : (res.p_path = '')
    // 递归过程中如果本次后端路由表中不存在 children 则为最后一级菜单
    if (
      !routeElement.children ||
      routeElement.children.length === 0 ||
      !asyncRouterElement.children ||
      asyncRouterElement.children.length === 0
    ) {
      if (routeElement.path == '') {
        res.meta.btnPermission = routeElement['perms']
      }
      arr1.push(res)
      continue
    }
    // children 存在
    res.children = []
    arr1.push(routeElement)
    generateRoutesByFrontEnd(routeElement.children, children, res.path)
  }
  return arr1
}

// 后端控制路由生成
const capitalizeFirstLetter = (str: string) => {
  return str.charAt(0).toLowerCase() + str.slice(1)
}
const getContentAfterLastSlash = (str: string) => {
  const lastIndex = str.lastIndexOf('/')
  if (lastIndex !== -1) {
    return str.substring(lastIndex + 1)
  } else {
    return str // 如果没有斜杠，则返回整个字符串
  }
}
// 转换数据
const transformRoute = (route: any): AppRouteRecordRaw => {
  const result = {
    path: '',
    name: ''
  }
  route.query ? (result['redirect'] = route.query) : undefined
  // 处理路由组件路径
  // 处理路由信息
  // TODO 首页信息待处理
  if (route.name == '首页') {
    const dash = {
      M: {
        path: '/dashboard',
        name: 'Dashboard',
        redirect: '/dashboard/index',
        meta: {}
      },
      C: {
        path: 'index',
        name: 'DashboardIndex',
        meta: {
          title: route.name,
          icon: route.icon,
          hidden: route.visible === '1' // 如果菜单状态为隐藏，则设置 hidden 为 true
        }
      }
    }
    return dash[route.menu_type]
  }
  if (route.menu_type === 'M') {
    result.meta = {
      title: route.name,
      icon: route.icon,
      hidden: route.visible === '1', // 如果菜单状态为隐藏，则设置 hidden 为 true
      alwaysShow: route.visible === '0'
    }
    result.path = route.component.includes('##') ? route.path : '/' + route.path
  } else {
    result.meta = {
      title: route.name,
      hidden: route.visible === '1' // 如果菜单状态为隐藏，则设置 hidden 为 true
    }
    result.name =
      route.name == '商品列表' ? 'ProductList' : getContentAfterLastSlash(route.component)
    result.path = capitalizeFirstLetter(getContentAfterLastSlash(route.component))
  }
  return result as AppRouteRecordRaw
}
export const generateRoutesByServer = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => {
  const res: AppRouteRecordRaw[] = []
  for (const route of routes) {
    const data: AppRouteRecordRaw = transformRoute(route)
    if (route.component) {
      const comModule =
        modules[`/src/views/${route.component}/index.vue`] ||
        modules[`/src/views/${route.component}/index.tsx`]
      const component = route.component as string
      if (!comModule && !component.includes('#')) {
        console.error(`未找到${route.component}.vue文件或${route.component}.tsx文件，请创建`)
      } else {
        // 动态加载路由文件，可根据实际情况进行自定义逻辑
        data.component =
          component === '#' ? Layout : component.includes('##') ? getParentLayout : comModule
      }
    }
    // 如果是目录类型的菜单，且有子菜单，则递归处理子菜单
    if (route.menu_type === 'M' && route.children && route.children.length > 0) {
      data.children = generateRoutesByServer(route.children)
    }
    res.push(data as AppRouteRecordRaw)
  }
  return res
}

export const pathResolve = (parentPath: string, path: string) => {
  if (isUrl(path)) return path
  const childPath = path.startsWith('/') || !path ? path : `/${path}`
  return `${parentPath}${childPath}`.replace(/\/\//g, '/').trim()
}

// 路由降级
export const flatMultiLevelRoutes = (routes: AppRouteRecordRaw[]) => {
  const modules: AppRouteRecordRaw[] = cloneDeep(routes)
  for (let index = 0; index < modules.length; index++) {
    const route = modules[index]
    if (!isMultipleRoute(route)) {
      continue
    }
    promoteRouteLevel(route)
  }
  return modules
}

// 层级是否大于2
const isMultipleRoute = (route: AppRouteRecordRaw) => {
  if (!route || !Reflect.has(route, 'children') || !route.children?.length) {
    return false
  }

  const children = route.children

  let flag = false
  for (let index = 0; index < children.length; index++) {
    const child = children[index]
    if (child.children?.length) {
      flag = true
      break
    }
  }
  return flag
}

// 生成二级路由
const promoteRouteLevel = (route: AppRouteRecordRaw) => {
  let router: Router | null = createRouter({
    routes: [route as RouteRecordRaw],
    history: createWebHashHistory()
  })

  const routes = router.getRoutes()
  addToChildren(routes, route.children || [], route)
  router = null

  route.children = route.children?.map((item) => omit(item, 'children'))
}

// 添加所有子菜单
const addToChildren = (
  routes: RouteRecordNormalized[],
  children: AppRouteRecordRaw[],
  routeModule: AppRouteRecordRaw
) => {
  for (let index = 0; index < children.length; index++) {
    const child = children[index]
    const route = routes.find((item) => item.name === child.name)
    if (!route) {
      continue
    }
    routeModule.children = routeModule.children || []
    if (!routeModule.children.find((item) => item.name === route.name)) {
      routeModule.children?.push(route as unknown as AppRouteRecordRaw)
    }
    if (child.children?.length) {
      addToChildren(routes, child.children, routeModule)
    }
  }
}
